package br.ufes.ceunes.poo.model.pojo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * Classe para objetos do tipo Cliente, onde serão contidos, identificadores e
 * métodos para o mesmo.
 */
@Entity
public class Cliente implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(nullable = false)
    private String nome;

    @Column
    private String endereco;

    @Column(nullable = false, unique = true)
    private String cpf;

    @Column
    private String telefone;

    @Column
    private String identidade;

    @Column
    private String email;

    @OneToMany(mappedBy = "cliente", fetch = FetchType.LAZY)
    private List<Pedido> listaVendas;

    /**
     * Método para instanciar a lista de pedidos do Cliente
     */
    public Cliente() {
        listaVendas = new ArrayList<Pedido>();
    }

    /**
     * Método para construção do Cliente
     *
     * obs.: reaproveita o contrutor que instancia a lista de pedidos do cliente
     *
     * @param nome - atribui o nome ao Cliente
     * @param cpf - atribui o CPF ao Cliente
     */
    public Cliente(String nome, String cpf) {
        this();
        this.nome = nome;
        this.cpf = cpf;
    }

    /**
     * Método para construção do Cliente
     *
     * obs.: reaproveita o construtor anterior
     *
     * @param nome - atribui o nome ao cliente
     * @param cpf - atribui o CPF ao Cliente
     * @param email - atribui o e-mail ao Cliente
     */
    public Cliente(String nome, String cpf, String email) {
        this(nome, cpf);
        this.email = email;
    }

    /**
     * Método para construção do Cliente
     *
     * obs.: reaproveita o construtor anterior
     *
     * @param nome - atribui o nome ao Cliente
     * @param endereco - atribui o endereço ao Cliente
     * @param cpf - atribui o CPF ao Cliente
     * @param telefone - atribui otelefone ao Cliente
     * @param identidade - atribui o numero de identidade ao Cliente
     * @param email - atribui o e-mail ao Cliente
     */
    public Cliente(String nome, String endereco, String cpf, String telefone, String identidade, String email) {
        this(nome, cpf, email);
        this.endereco = endereco;
        this.telefone = telefone;
        this.identidade = identidade;
    }

    /**
     * Método para retornar o nome do Cliente
     *
     * @return String - nome - nome do cliente
     */
    public String getNome() {
        return this.nome;
    }

    /**
     * Método para retornar o endereço do Cliente
     *
     * @return String - endereço - endereço do cliente
     */
    public String getEndereco() {
        return this.endereco;
    }

    /**
     * Método para retornar o CPF do Cliente
     *
     * @return String - cpf - CPF do Cliente
     */
    public String getCpf() {
        return this.cpf;
    }

    /**
     * Método para retornar o numero de telefone do Cliente
     *
     * @return String - telefone - numero de telefone do Cliente
     */
    public String getTelefone() {
        return this.telefone;
    }

    /**
     * Método para retornar o número de identidade do Cliente
     *
     * @return String - identidade - número de identidade do Cliente
     */
    public String getIdentidade() {
        return this.identidade;
    }

    /**
     * Método para retornar o e-mail do Cliente
     *
     * @return String - email - e-mail do Cliente
     */
    public String getEmail() {
        return this.email;
    }

    /**
     * Método para adicionar um pedido na lista de pedidos do Cliente
     *
     * @param pedido - pedido realizado pelo Cliente
     * @return List - listaVendas - lista de pedidos do Cliente
     */
    public boolean adicionaPedido(Pedido pedido) {
        return listaVendas.add(pedido);
    }

    /**
     * Método para retornar a lista de pedidos do Cliente
     *
     * @return List - listaVendas - lista de pedidos do Cliente
     */
    public List<Pedido> getPedidos() {
        return listaVendas;
    }

    /**
     * Método para retornar o ID do Cliente
     *
     * @return id - id do Cliente
     */
    public Integer getId() {
        return id;
    }

    /**
     * Método para alterar o ID do Cliente
     *
     * @param id - id atribuido ao Cliente
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * Método para alterar o endereço do Cliente
     *
     * @param endereço - endereço atribuido ao CLiente
     */
    public void setEndereco(String endereço) {
        this.endereco = endereço;
    }

    /**
     * Método para alterar o número de telefone do Cliente
     *
     * @param telefone - telefone atribuido ao cliente
     */
    public void setTelefone(String telefone) {
        this.telefone = telefone;

    }

    /**
     * Método para alterar o e-mail do Cliente
     *
     * @param email - e-mail atribuido ao Cliente
     */
    public void setEmail(String email) {
        this.email = email;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public void setIdentidade(String identidade) {
        this.identidade = identidade;
    }

    public void setCPF(String cpf) {
        this.cpf = cpf;
    }

    /**
     * Sobrescrição do método hashCode para agilizar a busca em collections
     *
     * @return hash - O método retorna um código hash de um objeto
     */
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 29 * hash + Objects.hashCode(this.id);
        return hash;
    }

    /**
     * Sobrescrição do método equals
     *
     * @param obj - objeto para comparação
     * @return boolean - false se não encontra, true caso contrário
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Cliente other = (Cliente) obj;
        return Objects.equals(this.id, other.id);
    }

}
